/*
 * All rights Reserved, Designed By cloudland Copyright(C) 2010-2014
 *
 * fileName:  TokenHelper.java
 * author:  lei
 * Company:  Cloudland Studio
 * Createdate:  2013-9-14 下午8:50:36
 *   
 * Modification  History:
 *     Date           Author        Version        
 * -------------------------------------------
 * 2013-9-14          Lei            1.0        
 *
 * Why & What is modified:
 * 1.0: 文件创建
 */
package org.cloudland.web.tag.support;

import java.math.BigInteger;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.cloudland.web.context.HttpHandle;

 /**
 * <pre> 
 * token 助手类，用于创建 token。防止页面重复提交，恶意请求。
 * 
 * 类使用在 {@link org.cloudland.web.tag.TokenTagFreemarker#exec(java.util.List)}
 * </pre>
 * @ClassName  TokenHelper
 * @author  lei
 * @version  %I%, %G%
 * @see  
 * @since   JDK1.6
 *
 */
public abstract class TokenHelper {

	/**
     * DEFAULT_TOKEN_NAME 默认存储的 Token 名称
     */
    public static final String DEFAULT_TOKEN_NAME = "Cloudland.Token";

    /**
     * RANDOM 随机数类
     */
    private static final Random RANDOM = new Random();
    
    /**
     * <pre>
     * getToken 获取 token 值。
     * </pre>
     *
     * @return   
     */
    public static String getToken() {
        HttpSession session = HttpHandle.getInstance().getRequest().getSession();
        session.setAttribute(DEFAULT_TOKEN_NAME, generateGUID());
        return String.valueOf(session.getAttribute(DEFAULT_TOKEN_NAME));
    }
    
    /**
     * 检查 Token 是否合法。<br>
     * <pre>
     * 检查此请求是否需要防重复提交控制，如果需要则对请求进行检查。用户可根据返回结果，决定请求是否继续。
     * 
     * true：表示请求没有问题。false：表示请求存在重复提交，或者恶意攻击。
     * </pre>
     *
     * @return   
     */
    public static boolean isValid() {
        boolean isBrowse = true;
        
        HttpServletRequest request = HttpHandle.getInstance().getRequest();
        Map<?, ?> paramNames = request.getParameterMap();
        if (paramNames.containsKey(DEFAULT_TOKEN_NAME)) {
            isBrowse = false;
        }
        
        if (!isBrowse) {
            HttpSession session = request.getSession();
            Object serverToken = session.getAttribute(DEFAULT_TOKEN_NAME);
            if (null == serverToken) {
                // TODO 重复提交
                return false;
            }
            
            isBrowse = serverToken.equals(request.getParameter(DEFAULT_TOKEN_NAME));
            session.removeAttribute(DEFAULT_TOKEN_NAME);
        }
        
        return isBrowse;
    }
    
    /**
     * <pre>
     * 生成 Token 随机数。
     * </pre>
     *
     * @return   
     */
    public static String generateGUID() {
        return new BigInteger(165, RANDOM).toString(64).toUpperCase();
    }
}
